﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.ComponentModel;
using BitmapTagger;
using BrainTechLLC;
using System.Threading;
using System.IO;

namespace ImageAppDataModels
{
    public partial class AdditionalJpegImageInfo : BaseNotifyPropertyChanged, IAdditionalImageInfo
    {
        public AdditionalJpegImageInfo(string fileName)
        {
            _fileName = fileName;
        }

        protected string _fileName;
        protected object _lockObjectTagger = new object();
        protected BitmapTagger.JpegTagger _tagger;

        public string Model { get { return Tagger.Model; } }
        public ushort? MeteringMode { get { return Tagger.MeteringMode; } }
        public string Make { get { return Tagger.Make; } }
        public ushort? SensingMethod { get { return Tagger.SensingMethod; } }
        public Rational ShutterSpeed { get { return Tagger.ShutterSpeed; } }
        public string Software { get { return Tagger.Software; } }
        public string UserComment { get { return Tagger.UserComment; } }
        public ushort? LightSource { get { return Tagger.LightSource; } }
        public ushort? ISOSpeedRatings { get { return Tagger.ISOSpeedRatings; } }
        public URational ExposureTime { get { return Tagger.ExposureTime; } }
        public URational FNumber { get { return Tagger.FNumber; } }
        public ushort? ExposureProgram { get { return Tagger.ExposureProgram; } }
        public DateTime? DateTimeOriginal { get { return Tagger.DateTimeOriginal; } }
        public DateTime? DateTimeDigitized { get { return Tagger.DateTimeDigitized; } }
        public string Copyright { get { return Tagger.Copyright; } }
        public string ImageDescription { get { return Tagger.ImageDescription; } }
        public URational Aperture { get { return Tagger.Aperture; } }
        public string Artist { get { return Tagger.Artist; } }
        public Rational Brightness { get { return Tagger.Brightness; } }
        public DateTime? PhotoDateTime { get { return Tagger.DateTime; } }

        private void RaiseTagPropertyChanged()
        {
            OnPropertyChanged("Aperture");
            OnPropertyChanged("Artist");
            OnPropertyChanged("Brightness");
            OnPropertyChanged("ImageDescription");
            OnPropertyChanged("PhotoDateTime");
            OnPropertyChanged("Model");
            OnPropertyChanged("MeteringMode");
            OnPropertyChanged("Make");
            OnPropertyChanged("SensingMethod");
            OnPropertyChanged("ShutterSpeed");
            OnPropertyChanged("Software");
            OnPropertyChanged("UserComment");
            OnPropertyChanged("LightSource");
            OnPropertyChanged("ISOSpeedRatings");
            OnPropertyChanged("ExposureTime");
            OnPropertyChanged("FNumber");
            OnPropertyChanged("ExposureProgram");
            OnPropertyChanged("DateTimeOriginal");
            OnPropertyChanged("DateTimeDigitized");
            OnPropertyChanged("Copyright");
        }

        public BitmapTagger.JpegTagger Tagger
        {
            get
            {
                if (_tagger == null)
                {
                    bool noGood = true;
                    int tries = 0;
                    bool setTagger = false;

                    while (noGood)
                    {
                        FileLocking.GetFileLock(_fileName);

                        try
                        {
                            EnterMonitor(_lockObjectTagger, 20);

                            try
                            {
                                if (_tagger == null)
                                {
                                    try
                                    {
                                        _tagger = new JpegTagger(_fileName);
                                        setTagger = true;
                                        noGood = false;
                                    }
                                    catch (IOException)
                                    {
                                        if (tries++ > 5)
                                            throw;

                                        Monitor.Exit(_lockObjectTagger);
                                        Console.WriteLine("UGH");
                                        Thread.Sleep(100);
                                        EnterMonitor(_lockObjectTagger, 20);
                                    }
                                }
                            }
                            finally
                            {
                                Monitor.Exit(_lockObjectTagger);
                            }
                        }
                        finally
                        {
                            FileLocking.ReleaseFileLock(_fileName);
                        }
                    }

                    if (setTagger)
                    {
                        OnPropertyChanged("Tagger");
                        RaiseTagPropertyChanged();
                    }
                }

                return _tagger;
            }
            set
            {
                if (_tagger != value)
                {
                    _tagger = value;

                    if (value != null)
                    {
                        OnPropertyChanged("Tagger");
                        RaiseTagPropertyChanged();
                    }
                }
            }
        }
    }

    public partial class EmptyImageInfo : BaseNotifyPropertyChanged, IAdditionalImageInfo
    {
        public EmptyImageInfo(string fileName)
        {
            _fileName = fileName;
        }

        protected string _fileName;

        public string Model { get { return string.Empty; } }
        public ushort? MeteringMode { get { return null; } }
        public string Make { get { return string.Empty; } }
        public ushort? SensingMethod { get { return null; } }
        public Rational ShutterSpeed { get { return null; } }
        public string Software { get { return string.Empty; } }
        public string UserComment { get { return string.Empty; } }
        public ushort? LightSource { get { return null; } }
        public ushort? ISOSpeedRatings { get { return null; } }
        public URational ExposureTime { get { return null; } }
        public URational FNumber { get { return null; } }
        public ushort? ExposureProgram { get { return null; } }
        public DateTime? DateTimeOriginal { get { return null; } }
        public DateTime? DateTimeDigitized { get { return null; } }
        public string Copyright { get { return string.Empty; } }
        public string ImageDescription { get { return string.Empty; } }
        public URational Aperture { get { return null; } }
        public string Artist { get { return string.Empty; } }
        public Rational Brightness { get { return null; } }
        public DateTime? PhotoDateTime { get { return null; } }
    }
}
